package com.ruoyi.common.utils.file;

import com.ruoyi.common.config.FtpConfig;
import com.ruoyi.common.exception.ServiceException;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.io.InputStream;
import java.net.SocketException;

/**
 * 描述 FTP文件上传工具类
 * 作者 ZhangPing
 * 创建时间 2023/9/25 15:20
 */
@Slf4j
@NoArgsConstructor
@Component
public class FtpUtil {

    @Autowired
    private FtpConfig ftpConfig;

    public void uploadFile(String ftpPath, String fileName, InputStream inputStream) {
        FTPClient ftpClient = loginFtp();
        try {
            //切换到工作目录
            changeWorkingDirectory(ftpClient, ftpPath);
            //工作模式被动
            ftpClient.enterLocalPassiveMode();
            //文件写入 远程文件名；输入流
            ftpClient.storeFile(fileName, inputStream);
        } catch (Exception e) {
            throw new ServiceException("文件上传失败");
        } finally {
            try {
                inputStream.close();
                ftpClient.logout();
                ftpClient.disconnect();
            } catch (Exception e) {}
        }
    }

    /**
     * 登录FPT
     * @return
     */
    private FTPClient loginFtp() {
        FTPClient ftpClient = new FTPClient();
        try {
            //连接
            ftpClient.connect(ftpConfig.getIp(), ftpConfig.getPort());
            //设置编码
            ftpClient.setControlEncoding("UTF-8");
            //登录
            ftpClient.login(ftpConfig.getUsername(), ftpConfig.getPassword());
            //设置文件类型放在登录之后否则出现乱码
            ftpClient.setFileType(FTPClient.BINARY_FILE_TYPE);
            if (!FTPReply.isPositiveCompletion(ftpClient.getReplyCode())) {
                ftpClient.disconnect();
                throw new ServiceException("未连接到FTP，用户名或密码错误");
            }
        } catch (SocketException e) {
            throw new ServiceException("FTP的IP地址错误");
        } catch (IOException e) {
            throw new ServiceException("FTP的端口错误");
        }
        return ftpClient;
    }

    /**
     * 删除文件
     * @param ftpPath
     * @return
     */
    public boolean deleteFile(String ftpPath) {
        boolean isSuccess = false;
        FTPClient ftpClient = loginFtp();
        try {
            // 检查文件是否存在
            FTPFile[] files = ftpClient.listFiles(ftpPath);
            if (files.length > 0) {  // 存在
                isSuccess = ftpClient.deleteFile(ftpPath);
            } else {  // 不存在
                isSuccess = true;
            }
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            if (ftpClient.isConnected()) {
                try {
                    ftpClient.disconnect();
                } catch (IOException ioe) {
                    ioe.printStackTrace();
                }
            }
        }
        return isSuccess;
    }

    /**
     * 切换工作目录
     * @param ftpClient
     * @param ftpPath
     * @throws IOException
     */
    private void changeWorkingDirectory(FTPClient ftpClient, String ftpPath) throws IOException {
        if (!ftpClient.changeWorkingDirectory(ftpPath)) {
            ftpClient.changeWorkingDirectory("/");
            String[] dirs = ftpPath.split("/");
            for (String dir : dirs) {
                if (!"".equals(dir)) {
                    ftpClient.makeDirectory(dir);
                    ftpClient.changeWorkingDirectory(dir);
                }
            }
        }
    }

}

